import { Controller, Post, Body, Ctx } from "koa-ts-controllers";
import { Context } from "koa";
import { RegesiterBody, LoginBody } from "../validators/User";
import { User as UserModel } from "../models/User";
import Boom from "@hapi/Boom";
import crypto from "crypto";
import jwt from "jsonwebtoken";
import configs from "../configs/index";

@Controller("/user")
export class UserController {
  /**
   * 用户注册
   */

  @Post("/register")
  async regesiter(@Ctx() ctx: Context, @Body() body: RegesiterBody) {
    let { name, password } = body;

    //  验证数据库中是否存在要注册的用户
    //  在sequelize中, 类对应的是表，对象对应的是数据

    let user = await UserModel.findOne({
      where: {
        name,
      },
    });

    //  检测用户名是否已被注册
    if (user) {
      throw Boom.conflict("注册失败", "用户名已被注册");
    }

    //  newUser 表示新创建的一个数据
    let newUser = new UserModel();
    newUser.name = name;
    newUser.password = password;

    //  将输入的账号密码存入数据库, 返回状态码201表示创建成功
    try {
      await newUser.save();
      ctx.status = 201;
      return {
        id: newUser.id,
        name: newUser.name,
        createdAt: newUser.createdAt,
      };
    } catch (e) {}
  }

  /**
   *  用户登录
   *
   */
  @Post("/login")
  async login(@Ctx() ctx: Context, @Body() body: LoginBody) {
    let { name, password } = body;

    let user = await UserModel.findOne({
      where: {
        name,
      },
    });

    if (user) {
      //  将输入的密码进行加密后
      const md5 = crypto.createHash("md5");
      password = md5.update(password).digest("hex");

      //  与服务端存在的密码进行对比
      if (password !== user.password) {
        throw Boom.forbidden("登录失败", "密码错误");
      }

      let userInfo = {
        id: user.id,
        name: user.name,
      };

      //  将用户信息加密, 加密后的token放到头部
      let token = jwt.sign(userInfo, configs.jwt.privateKey);

      ctx.set("authorization", token);
      return userInfo;
    } else {
      throw Boom.forbidden("登录失败", "用户不存在");
    }
  }
}
